﻿using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.ComponentModel;
using System.IO;
using MSocketCore.Hub;
using MSocketCore.Model;
using MSocketCore.MSocket;
using Topshelf;

namespace MSocketCore
{
    public class Program
    {
        private static IConfiguration _appConfiguration;

        public static void Main()
        {
            var rc = HostFactory.Run(x =>
            {
                var services = ConfigureServices();
                var serviceProvider = services.BuildServiceProvider();
                var config = serviceProvider.GetService<IOptions<MConfig>>();
                x.Service<RegService>(s =>
                {
                    s.ConstructUsing(() => new RegService(serviceProvider.GetService<ServerContainer>(), serviceProvider.GetService<MessageClient>()));
                    s.WhenStarted((s, hostControl) => s.Start(hostControl));
                    s.WhenStopped((s, hostControl) => s.Stop(hostControl));
                });

                x.RunAsLocalSystem();
                x.StartAutomatically();
                x.SetDescription(config.Value.HostDescription);
                x.SetDisplayName(config.Value.HostName);
                x.SetServiceName(config.Value.HostExeName);
                x.AddCommandLineDefinition("start", delegate (string s) { });
            });

            var exitCode = (int)Convert.ChangeType(rc, rc.GetTypeCode());
            Environment.ExitCode = exitCode;
        }

        private static IServiceCollection ConfigureServices()
        {
            IServiceCollection services = new ServiceCollection();
            var config = LoadConfiguration();
            services.Configure<MConfig>(config.GetSection("App"));

            services.AddAutoMapper(typeof(AutoMapperConfig));
            services.AddSingleton<MessageClient>();
            services.AddSingleton<ServerContainer>();
            
            services.AddLogging(configure =>
            {
                configure.ClearProviders();
                configure.AddLog4Net("config/log4net.config");
            });
   
            return services;
        }

        public static IConfiguration LoadConfiguration()
        {
            var env = Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT");
            var builder = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
#if DEBUG
            builder = builder.AddJsonFile($"appsettings.{env}.json", optional: true, reloadOnChange: true);
#endif

            return builder.Build();
        }
    }
}